<template>
  <div id="activities">
    <div class="newslist1">
      <div class="title-img">
        <img src="../../../static/images/icon/earth.svg" alt="">
        <span>新闻速递</span>
      </div>
      <ul class="news_liebiao news_sudi">
        <li class="weui-news-item" v-if="index == 0" v-for="(temp,index) in newsList" @click="toDetail(temp)">
          <div class="weui-news-text" >
            <div class="weui-news-title"><a href="javascript:void(0);"><span style="color: red">【新】</span>{{temp.title.substring(0,30)+"..."}}</a>
            </div>
          </div>
          <div class="weui-news-date">[{{ temp.createTime }}]</div>
        </li>
        <li class="weui-news-item"  v-if="index != 0" v-for="(temp,index) in newsList" @click="toDetail(temp)">
          <div class="weui-news-text">
            <div class="weui-news-title"><a href="javascript:void(0);">{{temp.title.substring(0,30)+"..."}}</a></div>
          </div>
          <div class="weui-news-date">[{{ temp.createTime }}]</div>
        </li>
      </ul>
    </div>
    <div class="newslist1 newslist2">
      <div class="title-img">
        <img src="../../../static/images/icon/notice.svg" alt="">
        <span>通知公告</span>
      </div>
      <ul class="news_liebiao news_sudi">
        <li class="weui-news-item" v-if="index == 0" v-for="(temp,index) in noticeList" @click="toDetail(temp)">
          <div class="weui-news-text">
            <div class="weui-news-title"><a href="javascript:void(0);"><span style="color: red">【新】</span>{{temp.title.substring(0,30)+"..."}}</a>
            </div>
          </div>
          <div class="weui-news-date">[{{ temp.createTime }}]</div>
        </li>
        <li class="weui-news-item" v-if="index != 0" v-for="(temp,index) in noticeList" @click="toDetail(temp)">
          <div class="weui-news-text">
            <div class="weui-news-title"><a href="javascript:void(0);">{{temp.title.substring(0,30)+"..."}}</a></div>
          </div>
          <div class="weui-news-date">[{{ temp.createTime }}]</div>
        </li>
      </ul>
    </div>
  </div>
</template>
<script>
import debounce from 'lodash.debounce'
import throttle from 'lodash.throttle'
import request from '../../utils/request'

export default {
  name: 'HotNews',
  props: {
    refList: {
      type: Array,
      default () {
        return [
        ]
      }
    },
    // 是否开启dom监听,dom有变化主动更新各个ref的offsetTop值
    watch: {
      type: Boolean,
      default: false
    },
    // 绑定scroll事件的dom的class
    // 该元素必须为定位元素或者最近的 table,td,th,body
    innerScroll: {
      type: Boolean,
      default: false
    },
    container: {
      type: String,
      // required: true
      required: false
      // default: ""
    },
    levelList: {
      type: Array,
      default () {
        return ['h2', 'h3', 'h4', 'h5']
      }
    },
    activeColor: {
      type: String,
      default: '#ff6633'
    },
    height: {
      type: String,
      default: ''
    },
    levelGap: {
      type: Number,
      default: 20
    },
    iconLeft: {
      type: Boolean,
      default: false
    },
    title: {
      type: String,
      default: ''
    },
    lineLeft: {
      type: Number,
      default: 22
    },
    lineShow: {
      type: Boolean,
      default: true
    }
  },
  data () {
    return {
      active: '',
      refTopMap: {},
      topList: [],
      reverseTopList: [],
      isBeforeDestroy: false,
      observer: null,
      itemClicking: false,
      debounceIntoView: null,
      throttleScroll: null,
      //新闻类
      newsList: [],
      //通知公告类
      noticeList:[],
      url: {
        newsList: '/sunNews/list'
      }
    }
  },

  created () {
    this.getNewsList()
    this.getNoticeList()
  },
  methods: {
    //跳转新闻详情页面
    toDetail(data){
      this.$router.push("./subjectInfo?id="+data.id)
    },
    //获取新闻
    getNewsList () {
      request.get(this.url.newsList,{
        params:{
          pageSize:5,
          category:1
        }
      })
        .then((res) => {
          if (res.data.success) {
            this.newsList = res.data.result.records
            console.log(this.newsList)
          }
        }).catch((error)=>{
        console.log(error)
      })
    },
    //获取通知公告
    getNoticeList () {
      request.get(this.url.newsList,{
        params:{
          pageSize:5,
          category:2
        }
      })
        .then((res) => {
          if (res.data.success) {
            this.noticeList = res.data.result.records
          }
        }).catch((error)=>{
        console.log(error)
      })
    },

    // 点击title
    activeAnchor (ref) {
      if (this.active === ref) return
      // 点击title 会触发scroll事件,在内容高度不够的情况下点击的title和active的title会有出入
      // 所以点击的时候先return掉scroll事件
      this.itemClicking = true
      this.scrollToEle.scrollTop = this.refTopMap[ref]
      this.active = ref
      this.debounceIntoView()
      // 等待页面滚动完成
      setTimeout(() => {
        this.itemClicking = false
      }, 150)
      this.$emit('title-click', ref)
    },
    // 获取ref的dom
    getRefDom (_ref) {
      const ref = this.$parent.$refs[_ref]
      if (Array.isArray(ref)) {
        return this.vueOrDom(ref[0])
      }
      return this.vueOrDom(ref)
    },
    // ref 是vue还是dom
    vueOrDom (ref) {
      if (ref instanceof HTMLElement) return ref
      if (ref._isVue) return ref.$el
    },
    // 获取ref offsetTop数组
    setTopList () {
      if (this.isBeforeDestroy) return
      this.topList = []
      if (this.refList.length) {
        this.topForList()
      } else {
        this.topForDom()
      }
      this.reverseTopList = JSON.parse(
        JSON.stringify(this.topList)
      ).reverse()
      // this.scrollHeight = this.scrollToEle.scrollHeight;
    },
    // scroll事件
    scrollHandle () {
      // 点击title的滚动不触发
      if (this.itemClicking) return
      const {scrollTop, clientHeight, scrollHeight} = this.scrollToEle
      // 到达顶部
      if (scrollTop === 0) {
        this.initActive()
        return
      }
      // 到达底部
      if (scrollTop + clientHeight >= scrollHeight) {
        this.initActive(true)
        return
      }
      this.reverseTopList.some(item => {
        if (scrollTop >= item.offsetTop) {
          this.active = item.ref
          this.debounceIntoView()
          return true
        }
        return false
      })
    },
    initActive (last) {
      if (!this.topList.length) return
      const index = last ? this.topList.length - 1 : 0
      this.active = this.topList[index].ref
      this.debounceIntoView(true)
    },
    activeIntoView (edge) {
      // 等active元素改变后
      this.$nextTick(() => {
        const activeEl = document.querySelector(
          '.side-catalog__list-item--active'
        )
        if (!activeEl) return
        // 顶部或者底部 scrollIntoView为smooth时无效
        activeEl.scrollIntoView({
          block: 'center',
          behavior: edge ? 'auto' : 'smooth'
        })
      })
    },
    getTitleMargin (level) {
      return level
        ? `${parseInt(level, 10) * this.levelGap}px`
        : this.levelGap + 'px'
    },
    // 需要为scrollElement设置相对定位(offsetParent)
    // offsetParent(定位元素或者最近的 table,td,th,body)
    setOffsetParent () {
      if (!this.innerScroll) return
      const ele = document.querySelector(this.container)
      if (ele.style.position) return
      ele.style.position = 'relative'
    },
    isChildren (level) {
      return level && level > 1
    },
    setWatcher () {
      // 设置dom监听
      this.observer = new MutationObserver(debounce(this.setTopList, 700))
      this.observer.observe(document.querySelector(this.container), {
        childList: true,
        subtree: true,
        attributes: true
      })
    },
    // 根据refList获取catalogList
    topForList () {
      this.refList.forEach(item => {
        const offsetTop = this.getRefDom(item.ref).offsetTop
        const title = item.title || this.getRefDom(item.ref).innerText
        this.topList.push({
          ref: item.ref,
          title,
          offsetTop,
          level: item.level
        })
        this.refTopMap[item.ref] = offsetTop
      })
    },
    // 根据levelList获取catalogList
    topForDom () {
      let headlevel = {}
      this.levelList.forEach((item, index) => {
        headlevel[item] = index + 1
      })
      const childrenList = Array.from(
        document.querySelectorAll(`${this.container} > *`)
      )
      childrenList.forEach((item, index) => {
        const nodeName = item.nodeName.toLowerCase()
        if (this.levelList.includes(nodeName)) {
          this.topList.push({
            ref: `${item.nodeName}-${index}`,
            title: item.innerText,
            offsetTop: item.offsetTop,
            level: headlevel[nodeName]
          })
          this.refTopMap[`${item.nodeName}-${index}`] = item.offsetTop
        }
      })
    }
  },
  computed: {
    scrollElement () {
      return this.innerScroll ? document.querySelector(this.container) : window
    },
    scrollToEle () {
      return this.innerScroll ? this.scrollElement : document.documentElement
    }
  },
  async mounted () {
    this.debounceIntoView = debounce(this.activeIntoView, 250)
    this.throttleScroll = throttle(this.scrollHandle, 200)
    await this.setOffsetParent()
    await this.setTopList()
    this.initActive()
    this.scrollElement.addEventListener('scroll', this.throttleScroll)
    if (!this.watch) return
    // 等待dom渲染完成之后监听
    setTimeout(() => {
      this.setWatcher()
    }, 200)
  },
  beforeDestroy () {
    if (!this.watch) return
    // beforeDestroy时,解绑dom监听之前,会触发observer监听的setTopList函数
    // 导致报错,需要用变量控制
    this.isBeforeDestroy = true
    // 解绑dom监听
    this.observer.disconnect()

    this.scrollElement.removeEventListener('scroll', this.throttleScroll)
  },
}
</script>
<style>

</style>
